/**
  ******************************************************************************
  * @file    bsp.c
  * @author  ashuai0110
  * @version V2.0
  * @date    2024-09-03
  * @brief   板级支持包
  *
  ******************************************************************************
  * @attention
  *
  * 版权声明:内容为编者(ashuai0110)原创,使用请注明出处,当然,你也可以不这样做^_^
  * 出处链接:https://gitee.com/ashuai0110/mcu_reuse_development_module.git
  *
  * Change Logs:
  * Date          Author        Notes
  * 2024-09-03    ashuai0110    完成基本内容
  *
  ******************************************************************************
  */

/* 包含头文件-----------------------------------------------------------------*/
#include "bsp.h"

/* 私有宏定义-----------------------------------------------------------------*/

/* 私有类型定义---------------------------------------------------------------*/

/* 私有变量-------------------------------------------------------------------*/

/* 全局变量-------------------------------------------------------------------*/

/* 私有函数原型---------------------------------------------------------------*/


/**
  * @brief  系统时钟初始化72MHz(HSE)
  *
  * @param  None
  *
  * @retval None
  */
static void rcc_clock_config(void)
{
    RCC_DeInit();

    RCC_HSEConfig(RCC_HSE_ON); /* 打开外部高速时钟HSE */
    while(RESET == RCC_GetFlagStatus(RCC_FLAG_HSERDY)); /* 等待时钟稳定 */

    RCC_HCLKConfig(RCC_SYSCLK_Div1); /* AHB clock(HCLK) = SYSCLK/1 (max:72MHz) */

    RCC_PCLK1Config(RCC_HCLK_Div2); /* APB1 clock(PCLK1) = HCLK/2 (max:36MHz) */

    RCC_PCLK2Config(RCC_HCLK_Div1); /* APB2 clock(PCLK2) = HCLK/1 (max:72MHz) */

    FLASH_SetLatency(FLASH_Latency_2); /* FLASH 2等待周期 */
    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); /* 使能FLASH预取缓冲区 */

    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); /* SYSCLK == 72MHz  PLLCLK = 8MHz*9 */
    RCC_PLLCmd(ENABLE); /* 使能PLL */
    while(RESET == RCC_GetFlagStatus(RCC_FLAG_PLLRDY)); /* 等待PLL稳定 */
    
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); /* 选择PLLCLK作为SYSCLK时钟源 */
    while(0x08 != RCC_GetSYSCLKSource()); /* 等待SYSCLK时钟源切换完成 */

    SysTick_Config(7200); /* systick初始化周期100ns */
}

/**
  * @brief  NVIC初始化
  *
  * @param  None
  *
  * @retval None
  */
static void nvic_config(void)
{
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); /* 设置中断优先级组4 */
}

/**
  * @brief  GPIO初始化
  *
  * @param  None
  *
  * @retval None
  */
static void gpio_config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); /* 开启GPIO时钟 */
    
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; /* 设置引脚号 */
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; /* 设置引脚模式 */
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; /* 设置引脚速度 */
    GPIO_Init(GPIOA, &GPIO_InitStructure); /* 初始化GPIO */
    
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; /* 设置引脚号 */
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; /* 设置引脚模式 */
    GPIO_Init(GPIOA, &GPIO_InitStructure); /* 初始化GPIO */
    
    GPIO_WriteBit(GPIOA, GPIO_Pin_8, Bit_SET); /* LED */
}

/**
  * @brief  BSP初始化
  *
  * @param  None
  *
  * @retval None
  */
void bsp_init(void)
{
    nvic_config();
    rcc_clock_config();
    gpio_config();
}

/**
  * @brief  led写IO状态
  *
  * @param  state : IO状态
  *
  * @retval None
  */
void bsp_led_write(uint8_t state)
{
    GPIO_WriteBit(GPIOA, GPIO_Pin_8, (BitAction)state);
}

/**
  * @brief  读测试输入IO状态
  *
  * @param  None
  *
  * @retval None
  */
uint8_t bsp_test_in_read(void)
{
    return GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_2);
}
